#include "AComb_LTV.h" 
void AComb_LTV_Vector_in::Set(std::vector<TLorentzVector> &input, int kind){
	if(kind==1){
		in1=input;
		num1=in1.size();
		_kind=1;
	}
	else if(kind==-1){
		in2=input;
		num2=in2.size();
		_kind=-1;
	}
	else{
		ShowMessage(2,"In AComb_LTV_Vector_in::Set(vector<TLV> input, kind), wrong input kind, if only one input vector, kind only can be 1 or -1");
		exit(0);
	}
}

void AComb_LTV_Vector_in::Set(std::vector<TLorentzVector> &input1, std::vector<TLorentzVector> &input2){
	in1=input1;
	in2=input2;
	num1=in1.size();
	num2=in2.size();
	if(num1==0&&num2==0){
		_kind = 0;
	}
	else if(num1==0&&num2!=0){
		_kind = -1;
	}
	else if(num1!=0&&num2==0){
		_kind = 1;
	}
	else{
		_kind=2;
	}
}

void AComb_LTV_Vector_in::Add(std::vector<TLorentzVector> &input, int kind){
	for(int i=0; i<input.size(); i++){
		if(kind==1){
			in1.push_back(input[i]);
		}
		else if(kind==-1){
			in2.push_back(input[i]);
		}
	}
}

void AComb_LTV_Vector_in::Add(TLorentzVector &input, int kind){
	if(kind==1){
		in1.push_back(input);
	}
	else if(kind==-1){
		in2.push_back(input);
	}
}

//for align kind and input
void AComb_LTV_Vector_in::Set_Kind(int input_kind){
	_kind=input_kind;
	if(input_kind==1){
		in2.clear();
	}
	else if(input_kind==-1){
		in1.clear();
	}
}

void AComb_LTV_Vector_in::Switch(){
	std::vector<TLorentzVector> tmp;
	tmp=in2;
	in2=in1;
	in1=tmp;
	tmp.clear();
}

void AComb_LTV_Vector_in::Clear(){
	in1.clear();
	in2.clear();
	_kind=0;
}

std::vector<TLorentzVector> AComb_LTV_Vector_in::Select_Choosed(int pos1, int pos2){
	//ShowMessage(2,"in AComb_LTV_Vector_in:: in Select_Choosd", pos1, pos2, _kind);
	std::vector<TLorentzVector> choosed;
	if(_kind==1){
		if(pos1>in1.size()||pos2>in1.size()){
			return {};
		}
		choosed.push_back(in1.at(pos1));
		choosed.push_back(in1.at(pos2));
	}
	else if(_kind==-1){
		if(pos1>in2.size()||pos2>in2.size()){
			return {};
		}
		choosed.push_back(in2.at(pos1));
		choosed.push_back(in2.at(pos2));
	}
	else if(_kind==2){
		if(pos1>in1.size()||pos2>in2.size()){
			return {};
		}
		choosed.push_back(in1.at(pos1));
		choosed.push_back(in2.at(pos2));
	}
	//ShowMessage(2,"in AComb_LTV_Vector_in::Select_Choosd, choosed",choosed);
	return(choosed);
}


void AComb_LTV_Vector_in::Print(int level, std::string str){
	ShowMessage(level,"AComb_LTV_Vector_in: for", str);
	ShowMessage(level+1,"AComb_LTV_Vector_in: kind", _kind);
	ShowMessage(level+1,"AComb_LTV_Vector_in: in1 ", in1);
	ShowMessage(level+1,"AComb_LTV_Vector_in: in2 ", in2);
}




void AComb_LTV_Vector_out::Assign_Variables(CDraw &para, AVariables &var){
	ShowMessage(2,"in AComb_LTV_Vector_out::Assign_Variables,  var size before",var.var.size());

	var.Assign_Variables(comb.M());
	var.Assign_Variables(comb.Pt());
	var.Assign_Variables(comb.Eta());
	var.Assign_Variables(mt);

	if (angle_switch["out1_out1"]){
		for(int iter_angle=0; iter_angle < angle.out1_out1_angle.size(); iter_angle++){
			var.Assign_Variables(angle.out1_out1_angle[iter_angle]);
		}
	}
	if (angle_switch["out2_out2"]){
		for(int iter_angle=0; iter_angle < angle.out2_out2_angle.size(); iter_angle++){
			var.Assign_Variables(angle.out2_out2_angle[iter_angle]);
		}
	}
	if (angle_switch["out1_out2"]){
		for(int iter_angle=0; iter_angle < angle.out1_out2_angle.size(); iter_angle++){
			var.Assign_Variables(angle.out1_out2_angle[iter_angle]);
		}
	}
	if (angle_switch["out1_comb"]){
		for(int iter_angle=0; iter_angle < angle.out1_comb_angle.size(); iter_angle++){
			var.Assign_Variables(angle.out1_comb_angle[iter_angle]);
		}
	}
	if (angle_switch["out2_comb"]){
		for(int iter_angle=0; iter_angle < angle.out2_comb_angle.size(); iter_angle++){
			var.Assign_Variables(angle.out2_comb_angle[iter_angle]);
		}
	}
	if (angle_switch["left1_left1"]){
		for(int iter_angle=0; iter_angle < angle.left1_left1_angle.size(); iter_angle++){
			var.Assign_Variables(angle.left1_left1_angle[iter_angle]);
		}
	}
	if (angle_switch["left2_left2"]){
		for(int iter_angle=0; iter_angle < angle.left2_left2_angle.size(); iter_angle++){
			var.Assign_Variables(angle.left2_left2_angle[iter_angle]);
		}
	}
	if (angle_switch["left1_left2"]){
		for(int iter_angle=0; iter_angle < angle.left1_left2_angle.size(); iter_angle++){
			var.Assign_Variables(angle.left1_left2_angle[iter_angle]);
		}
	}
	if (angle_switch["left1_comb"]){
		for(int iter_angle=0; iter_angle < angle.left1_comb_angle.size(); iter_angle++){
			var.Assign_Variables(angle.left1_comb_angle[iter_angle]);
		}
	}
	if (angle_switch["left2_comb"]){
		for(int iter_angle=0; iter_angle < angle.left2_comb_angle.size(); iter_angle++){
			var.Assign_Variables(angle.left2_comb_angle[iter_angle]);
		}
	}
	if (angle_switch["out1_left1"]){
		for(int iter_angle=0; iter_angle < angle.out1_left1_angle.size(); iter_angle++){
			var.Assign_Variables(angle.out1_left1_angle[iter_angle]);
		}
	}
	if (angle_switch["out1_left2"]){
		for(int iter_angle=0; iter_angle < angle.out1_left2_angle.size(); iter_angle++){
			var.Assign_Variables(angle.out1_left2_angle[iter_angle]);
		}
	}
	if (angle_switch["out2_left1"]){
		for(int iter_angle=0; iter_angle < angle.out2_left1_angle.size(); iter_angle++){
			var.Assign_Variables(angle.out2_left1_angle[iter_angle]);
		}
	}
	if (angle_switch["out2_left2"]){
		for(int iter_angle=0; iter_angle < angle.out2_left2_angle.size(); iter_angle++){
			var.Assign_Variables(angle.out2_left2_angle[iter_angle]);
		}
	}
}

//multi-cuts
void AComb_LTV_Vector_out::Set(std::vector<TLorentzVector> &output, std::vector<TLorentzVector> &input_left, int kind){
	if(kind==1){
		out1     = output;
		left1    = input_left;
		num_out1 = out1.size();
		num_left1= left1.size();
		_kind    = 1;
	}
	else if(kind==-1){
		out2     = output;
		left2    = input_left;
		num_out2 = out2.size();
		num_left2= left2.size();
		_kind    = -1;
	}
	else{
		ShowMessage(2,"in AComb_LTV_Vector_out::Set(vector, vector, int),  wrong input kind, only can be 1 or -1");
		exit(0);
	}
}

void AComb_LTV_Vector_out::Set(std::vector<TLorentzVector> &output1, std::vector<TLorentzVector> &output2, std::vector<TLorentzVector> &input_left1, std::vector<TLorentzVector> &input_left2){
	out1 = output1;
	out2 = output2;
	left1= input_left1;
	left2= input_left2;
	num_out1=out1.size();
	num_out2=out2.size();
	num_left1=left1.size();
	num_left2=left2.size();
	_kind=2;
}

void AComb_LTV_Vector_out::Set(std::vector<TLorentzVector> &output, int num_filled_out, int kind){
	if(kind==1){
		out1 .assign(output.begin(),output.begin()+num_filled_out);
		left1.assign(output.begin()+num_filled_out+1,output.end());
		num_out1=out1.size();
		num_left1=left1.size();
		_kind=1;
	}
	else if(kind==-1){
		out2 .assign(output.begin(),output.begin()+num_filled_out);
		left2.assign(output.begin()+num_filled_out+1,output.end());
		num_out2=out2.size();
		num_left2=left2.size();
		_kind=-1;
	}
	else{
		ShowMessage(2,"in AComb_LTV_Vector_out::Set(vector, int, int),  wrong input kind, only can be 1 or -1");
		exit(0);
	}
}

void AComb_LTV_Vector_out::Set(std::vector<TLorentzVector> &output1, int num_filled_out1, std::vector<TLorentzVector> &output2, int num_filled_out2){
	out1 .assign(output1.begin(),output1.begin()+num_filled_out1);
	left1.assign(output1.begin()+num_filled_out1+1,output1.end());
	out2 .assign(output2.begin(),output2.begin()+num_filled_out2);
	left2.assign(output2.begin()+num_filled_out2+1,output2.end());
	num_out1=out1.size();
	num_out2=out2.size();
	num_left1=left1.size();
	num_left2=left2.size();
	_kind=2;
}


void AComb_LTV_Vector_out::Set_Angle(){
	angle.Set_Angle(out1, out2, left1, left2, comb);
	angle.Set_Title(_title);
}

void AComb_LTV_Vector_out::Set_DeltaR(){
	deltar.Set_DeltaR(out1, out2, left1, left2, comb);
	deltar.Set_Title(_title);
}

void AComb_LTV_Vector_out::Set_DeltaPhi(){
	deltaphi.Set_DeltaPhi(out1, out2, left1, left2, comb);
	deltaphi.Set_Title(_title);
}

void AComb_LTV_Vector_out::Set_Distance(){
	Set_Angle();
	Set_DeltaR();
	Set_DeltaPhi();
}



void AComb_LTV_Vector_out::Add(std::vector<TLorentzVector> &output, int kind){
	for(int i=0; i<output.size(); i++){
		if(kind==1){
			out1.push_back(output[i]);
		}
		else if(kind==-1){
			out2.push_back(output[i]);
		}
	}
}

void AComb_LTV_Vector_out::Add(TLorentzVector &output, int kind){
	if(kind==1){
		out1.push_back(output);
	}
	else if(kind==-1){
		out2.push_back(output);
	}
}

void AComb_LTV_Vector_out::Add_Left(std::vector<TLorentzVector> &left, int kind){
	for(int i=0; i<left.size(); i++){
		if(kind==1){
			left1.push_back(left[i]);
		}
		else if(kind==-1){
			left2.push_back(left[i]);
		}
	}
}

void AComb_LTV_Vector_out::Add_Left(TLorentzVector &left, int kind){
	if(kind==1){
		left1.push_back(left);
	}
	else if(kind==-1){
		left2.push_back(left);
	}
}

void AComb_LTV_Vector_out::Add_Comb(TLorentzVector &comb_input){
	comb = comb_input;
}

void AComb_LTV_Vector_out::Clear(){
	out1.clear();
	out2.clear();
	left1.clear();
	left2.clear();
	comb.SetPxPyPzE(0,0,0,0);
	_kind=0;
}



int AComb_LTV_Vector_out::Num(std::string name){
	if(name == ""){
		return(num_out1+num_out2+num_left1+num_left2);
	}
	else if(name == "out1_out1"){
		return(angle.Num("out1_out1"));
	}
	else if(name == "out1_out2"){
		return(angle.Num("out1_out2"));
	}
	else if(name == "out1_comb"){
		return(angle.Num("out1_comb"));
	}
	else if(name == "out1_left1"){
		return(angle.Num("out1_left1"));
	}
	else if(name == "out1_left2"){
		return(angle.Num("out1_left2"));
	}

	else if(name == "out2_out2"){
		return(angle.Num("out2_out2"));
	}
	else if(name == "out2_comb"){
		return(angle.Num("out2_comb"));
	}
	else if(name == "out2_left1"){
		return(angle.Num("out2_left1"));
	}
	else if(name == "out2_left2"){
		return(angle.Num("out2_left2"));
	}


	else if(name == "left1_comb"){
		return(angle.Num("left1_comb"));
	}
	else if(name == "left1_left1"){
		return(angle.Num("left1_left1"));
	}
	else if(name == "left1_left2"){
		return(angle.Num("left1_left2"));
	}

	else if(name == "left2_comb"){
		return(angle.Num("left2_comb"));
	}
	else if(name == "left2_left2"){
		return(angle.Num("left2_left2"));
	}
	return(-1);

}

void AComb_LTV_Vector_out::Set_Angle_Switch(){

	if(_kind==1 ){
		angle_switch["out1_out1"]  = true;
		angle_switch["out1_out2"]  = false;
		angle_switch["out2_out2"]  = false;
		angle_switch["out1_comb"]  = true;
		angle_switch["out2_comb"]  = false;
		angle_switch["out1_left1"] = false;
		angle_switch["out1_left2"] = false;
		angle_switch["out2_left1"] = false;
		angle_switch["out2_left2"] = false;
		angle_switch["left1_comb"]  = false;
		angle_switch["left2_comb"]  = false;
		angle_switch["left1_left1"] = false;
		angle_switch["left1_left2"] = false;
		angle_switch["left2_left2"] = false;
	}
	else if(_kind==-1){
		angle_switch["out1_out1"]  = false;
		angle_switch["out1_out2"]  = false;
		angle_switch["out2_out2"]  = true;
		angle_switch["out1_comb"]  = false;
		angle_switch["out2_comb"]  = true;
		angle_switch["out1_left1"] = false;
		angle_switch["out1_left2"] = false;
		angle_switch["out2_left1"] = false;
		angle_switch["out2_left2"] = false;
		angle_switch["left1_comb"]  = false;
		angle_switch["left2_comb"]  = false;
		angle_switch["left1_left1"] = false;
		angle_switch["left1_left2"] = false;
		angle_switch["left2_left2"] = false;
	}
	else if(_kind==2){
		angle_switch["out1_out1"]  = true;
		angle_switch["out1_out2"]  = true;
		angle_switch["out2_out2"]  = true;
		angle_switch["out1_comb"]  = true;
		angle_switch["out2_comb"]  = true;
		angle_switch["out1_left1"] = false;
		angle_switch["out1_left2"] = false;
		angle_switch["out2_left1"] = false;
		angle_switch["out2_left2"] = false;
		angle_switch["left1_comb"]  = false;
		angle_switch["left2_comb"]  = false;
		angle_switch["left1_left1"] = false;
		angle_switch["left1_left2"] = false;
		angle_switch["left2_left2"] = false;
	}

}


void AComb_LTV_Vector_out::Set_Kind(int input_kind){
	_kind=input_kind;
	if(input_kind==1){
		out2.clear();
	}
	else if(input_kind==-1){
		out1.clear();
	}
}

void AComb_LTV_Vector_out::Switch(){
	std::vector<TLorentzVector> tmp;
	tmp=out2;
	out2=out1;
	out1=tmp;
	tmp.clear();
}

void AComb_LTV_Vector_out::Set_Out_with_Pos(int pos1, int pos2, AComb_LTV_Vector_in &in){
	std::vector<TLorentzVector> choosed=in.Select_Choosed(pos1, pos2);
	//ShowMessage(2,"in AComb_LTV_Vector_out::Set_Out_with_Pos", choosed);
	Set_Kind(in.Kind());
	if(_kind==1){
		out1.push_back(choosed[0]);
		out1.push_back(choosed[1]);
	}
	else if(_kind==-1){
		out2.push_back(choosed[0]);
		out2.push_back(choosed[1]);
	}
	else if(_kind==2){
		out1.push_back(choosed[0]);
		out2.push_back(choosed[1]);
	}
}


void AComb_LTV_Vector_out::Set_Left_with_Pos(int pos1, int pos2, AComb_LTV_Vector_in &in){

	//ShowMessage(2,"in AComb_LTV_Vector_out::Set_Left_with_Pos", _kind);
	//in.Print("in AComb_LTV_Vector_out::Set_Left_with_Pos");
	if(_kind==1){
		for(int loop1=0;loop1<in.num1;loop1++){
			if(loop1==pos1||loop1==pos2){continue;}
			left1.push_back(in.in1.at(loop1));
		}
	}
	else if(_kind==-1){
		for(int loop1=0;loop1<in.num2;loop1++){
			if(loop1==pos1||loop1==pos2){continue;}
			left2.push_back(in.in2.at(loop1));
		}
	}
	else if(_kind==2){
		for(int loop1=0;loop1<in.num1;loop1++){
			if(loop1==pos1){continue;}
			left1.push_back(in.in1.at(loop1));
		}

		for(int loop1=0;loop1<in.num2;loop1++){
			if(loop1==pos2){continue;}
			left2.push_back(in.in2.at(loop1));
		}
	}
}

void AComb_LTV_Vector_out::Set_Comb(){
	if(_kind==1){
		comb = out1[0]+out1[1];
		mt = TLV_Mt(out1[0], out1[1]);
	}
	else if(_kind==-1){
		comb = out2[0]+out2[1];
		mt = TLV_Mt(out2[0], out2[1]);
	}
	else if(_kind==2){
		for(int i=0;i<out1.size();i++){
			comb = out1[i]+out2[i];
			mt = TLV_Mt(out1[i], out2[i]);
		}
	}
}

void AComb_LTV_Vector_out::Set_Comb_with_Pos(int pos1, int pos2){
	if(_kind==1){
		comb = out1[pos1]+out1[pos2];
		mt = TLV_Mt(out1[pos1], out1[pos2]);
	}
	else if(_kind==-1){
		comb = out2[pos1]+out2[pos2];
		mt = TLV_Mt(out2[pos1], out2[pos2]);
	}
	else if(_kind==2){
		TLorentzVector out1_all, out2_all;
		for(int i=0;i<out1.size();i++){
			out1_all += out1[i];
		}
		for(int i=0;i<out2.size();i++){
			out2_all += out2[i];
		}
		comb = out1_all+out2_all;
		mt = TLV_Mt(out1_all, out2_all);
	}
}



void AComb_LTV_Vector_out::Set_Choosed_with_Pos(int pos1, int pos2, AComb_LTV_Vector_in &in){
	Set_Out_with_Pos(pos1, pos2, in);
	Set_Left_with_Pos(pos1, pos2, in);
	Set_Comb();
}






void AComb_LTV_Vector_out::Print(int level, std::string str){
	if(str!=""){
		ShowMessage(level,"AComb_LTV_Vector_out: for", str);
	}
	else{
		ShowMessage(level,"AComb_LTV_Vector_out: for", _title);
	}
	ShowMessage(level,"AComb_LTV_Vector_out: out1", out1);
	ShowMessage(level,"AComb_LTV_Vector_out: out2", out2);
	ShowMessage(level,"AComb_LTV_Vector_out: comb", comb);
	ShowMessage(level,"AComb_LTV_Vector_out: mt");
	std::cout << mt << std::endl;
	ShowMessage(level,"AComb_LTV_Vector_out: left1", left1);
	ShowMessage(level,"AComb_LTV_Vector_out: left2", left2);
	angle.Print(level+1);
	deltar.Print(level+1);
	deltaphi.Print(level+1);
}


void AComb_LTV::Set_Title(std::string title){
	_title = title;
}


void AComb_LTV::Set_Cut(ACuts &input_cut){
	cuts=input_cut;
}

void AComb_LTV::Set_Kind(int input_kind){
	if(input_kind==1){
		out.left2=in.in2;
	}
	else if(input_kind==-1){
		out.left1=in.in1;
	}
	in.Set_Kind(input_kind);
	out.Set_Kind(input_kind);
}

void AComb_LTV::Set_In(std::vector<TLorentzVector> &input, int kind){
	in.Set(input, kind);
	in.Set_Title(_title);
	_Judge_in=true;
}

void AComb_LTV::Set_In(std::vector<TLorentzVector> &input_TLV, ACuts &input_cut, int kind){
	in.Set(input_TLV, kind);
	in.Set_Title(_title);
	Set_Cut(input_cut);
	_Judge_in=true;
}

void AComb_LTV::Set_In(std::vector<TLorentzVector> &input1, std::vector<TLorentzVector> &input2){
	in.Set(input1, input2);
	in.Set_Title(_title);
	_Judge_in=true;
}

void AComb_LTV::Set_In(std::vector<TLorentzVector> &input1, std::vector<TLorentzVector> &input2, ACuts &input_cut){
	in.Set(input1, input2);
	in.Set_Title(_title);
	Set_Cut(input_cut);
	_Judge_in=true;
}

void AComb_LTV::Add_In(std::vector<TLorentzVector> &input, int kind){
	in.Add(input, kind);
	_Judge_in=true;
}

void AComb_LTV::Add_In(TLorentzVector &input, int kind){
	in.Add(input, kind);
	_Judge_in=true;
}

void AComb_LTV::Set_Out(std::vector<TLorentzVector> &output1, std::vector<TLorentzVector> &input_left1, int kind){
	out.Set(output1, input_left1, kind);
	out.Set_Title(_title);
	_Judge_out=true;
}

void AComb_LTV::Set_Out(std::vector<TLorentzVector> &output1, std::vector<TLorentzVector> &output2, std::vector<TLorentzVector> &input_left1, std::vector<TLorentzVector> &input_left2){
	out.Set(output1, output2, input_left1, input_left2);
	out.Set_Title(_title);
	_Judge_out=true;
}

void AComb_LTV::Set_Out(std::vector<TLorentzVector> &output1, int num_filled_out1, int kind){
	out.Set(output1, num_filled_out1, kind);
	out.Set_Title(_title);
	_Judge_out=true;
}

void AComb_LTV::Set_Out(std::vector<TLorentzVector> &output1, int num_filled_out1, std::vector<TLorentzVector> &output2, int num_filled_out2){
	out.Set(output1, num_filled_out1, output2, num_filled_out2);
	out.Set_Title(_title);
	_Judge_out=true;
}

void AComb_LTV::Set_Out_with_Pos(int pos1, int pos2){
	if(!_Judge_in){ShowMessage(2,"no input in AComb_LTV"); return;}
	//in.Print("in AComb_LTV::Set_Out_with_Pos");
	out.Set_Choosed_with_Pos(pos1, pos2, in);
}


void AComb_LTV::Add_Out(std::vector<TLorentzVector> &output, int kind){
	out.Add(output, kind);
	_Judge_out=true;
}

void AComb_LTV::Add_Out(TLorentzVector &output, int kind){
	out.Add(output, kind);
	_Judge_out=true;
}

void AComb_LTV::Add_Left(std::vector<TLorentzVector> &left_in, int kind){
	out.Add_Left(left_in, kind);
	_Judge_out=true;
}

void AComb_LTV::Add_Left(TLorentzVector &left_in, int kind){
	out.Add_Left(left_in, kind);
	_Judge_out=true;
}

void AComb_LTV::Add_Comb(TLorentzVector &comb_in){
	out.Add_Comb(comb_in);
	_Judge_out=true;
}

void AComb_LTV::Set_Comb_with_Pos(int pos1, int pos2){
	out.Set_Comb_with_Pos(pos1, pos2);
}

void AComb_LTV::Set_Angle(){
	out.Set_Angle();
}

void AComb_LTV::Set_DeltaR(){
	out.Set_DeltaR();
}

void AComb_LTV::Set_DeltaPhi(){
	out.Set_DeltaPhi();
}

void AComb_LTV::Set_Distance(){
	out.Set_Distance();
}

void AComb_LTV::Print(int level, std::string str){
	if(str!=""){
		ShowMessage(level,"AComb_LTV contents for ", str);
	}
	else{
		ShowMessage(level,"AComb_LTV contents for ", _title);
	}
	cuts.Print(level+1);
	in.Print(level+1);
	out.Print(level+1);
}

void AComb_LTV::Flow_In_to_Out(){
	out.out1=in.in1;
	out.out2=in.in2;
	in.in1.clear();
	in.in2.clear();
}

void AComb_LTV::Flow_In_to_Left(){
	out.left1=in.in1;
	out.left2=in.in2;
	in.in1.clear();
	in.in2.clear();
}


void AComb_LTV::Transfer_Out(AComb_LTV &input){
	in.in1=input.out.out1;
	in.in2=input.out.out2;
}

void AComb_LTV::Transfer_Left(AComb_LTV &input){
	in.in1=input.out.left1;
	in.in2=input.out.left2;
}

bool AComb_LTV::Combine_SameFS(){
	int count1 = -10,count2 = -10;
	float min_value= 100000.0;
	float re_value= 100000.0;
	TLorentzVector mom1,mom2;
	std::vector<TLorentzVector> TLV;
	if(in.Kind()==1){
		TLV=in.in1;
	}
	else if(in.Kind()==-1){
		TLV=in.in2;
	}
	else{
		ShowMessage(2,"in AComb_LTV::Combine_SameFS, Wrong in.Kind()", in.Kind());
		exit(0);
	}
	for(int loop1=0;loop1<in.num1-1;loop1++){
		for(int loop2=loop1+1;loop2<in.num1;loop2++){
			mom1 = TLV[loop1];
			mom2 = TLV[loop2];
			bool judge=Combine2_direct(mom1, mom2, cuts, re_value);
			if(judge && std::abs(re_value-cuts.m.obj)<std::abs(min_value-cuts.m.obj)){
				count1 = loop1;
				count2 = loop2;
				min_value = re_value;
			}
		}
	} 
	if(count1!=-10&& count2!=-10){
		out.Set_Kind(in.Kind());
		Set_Out_with_Pos(count1, count2);
	}
	else{
		return(false);
		ShowMessage(2,"in AComb_LTV::Combine_SameFS, Wrong after combine", count1, count2, cuts.m.obj, re_value);
	}
	return(true);

}

bool AComb_LTV::Combine_DifferentFS(){
	int count1 = -10,count2 = -10;
	float min_value= 100000.0;
	float re_value = 100000.0;
	float obj_value= 100000.0;
	TLorentzVector mom1,mom2;

	if(in.Kind()!=2){
		ShowMessage(2,"in AComb_LTV::Combine_DifferentFS, Wrong in.Kind()", in.Kind());
		exit(0);
	}
	for(int loop1=0;loop1<in.num1;loop1++){
		for(int loop2=0;loop2<in.num2;loop2++){
			mom1 = in.in1[loop1];
			mom2 = in.in2[loop2];
			bool judge=Combine2_direct(mom1, mom2, cuts, re_value);
			if(judge && std::abs(re_value-cuts.m.obj)<std::abs(min_value-cuts.m.obj)){
				count1 = loop1;
				count2 = loop2;
				min_value = re_value;
			}
		}
	} 
	if(count1!=-10&& count2!=-10){
		out.Set_Kind(in.Kind());
		Set_Out_with_Pos(count1, count2);
		return(true);
	}
	else{return(false);}

}

std::string AComb_LTV::Title(){
	return(_title);
}

std::vector<TLorentzVector> AComb_LTV::In(){
	if(in.Kind()==1){
		return(in.in1);
	}
	if(in.Kind()==-1){
		return(in.in2);
	}
	return(in.in1+in.in2);
}

std::vector<TLorentzVector> AComb_LTV::In_All(){
	return(in.in1+in.in2);
}

std::vector<TLorentzVector> AComb_LTV::Out(){
	if(out.Kind()==1){
		return(out.out1);
	}
	if(out.Kind()==-1){
		return(out.out2);
	}
	return(out.out1+out.out2);
}

std::vector<TLorentzVector> AComb_LTV::Out_All(){
	return(out.out1+out.out2);
}

std::vector<TLorentzVector> AComb_LTV::Left(){
	if(out.Kind()==1){
		return(out.left1);
	}
	if(out.Kind()==-1){
		return(out.left2);
	}
	return(out.left1+out.left2);
}

std::vector<TLorentzVector> AComb_LTV::Left_All(){
	return(out.left1+out.left2);
}

TLorentzVector AComb_LTV::Comb(){
	return(out.comb);
}



//
//
//
//
//
//
